package com.evan.webadmin.biz.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evan.common.core.constant.PersonnelTypeEnum;
import com.evan.common.core.exception.MyRuntimeException;
import com.evan.webadmin.biz.dao.ExamPaperDetailMapper;
import com.evan.webadmin.biz.dao.ExamPaperMapper;
import com.evan.webadmin.biz.dto.ExamPaperDto;
import com.evan.webadmin.biz.model.ExamPaper;
import com.evan.webadmin.biz.model.ExamPaperDetail;
import com.evan.webadmin.biz.service.IExamPaperDetailService;
import com.evan.webadmin.biz.service.IExamPaperService;
import com.evan.webadmin.biz.service.IExamService;
import com.evan.webadmin.biz.service.ISubjectService;
import com.evan.webadmin.biz.vo.SubjectFrontVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 试卷表 服务实现类
 * </p>
 *
 * @author Pavel
 * @since 2025-02-28
 */
@Service
public class ExamPaperServiceImpl extends ServiceImpl<ExamPaperMapper, ExamPaper> implements IExamPaperService {

    @Autowired
    private IExamPaperDetailService detailService;
    @Autowired
    private ExamPaperMapper examPaperMapper;
    @Autowired
    private ExamPaperDetailMapper examPaperDetailMapper;
    @Autowired
    private ISubjectService subjectService;
    @Autowired
    private IExamService examService;

    @Override
    public List<ExamPaper> findExamPaperByTypeAndName(Integer personnelType, Integer moduleType, String paperName) {
        LambdaQueryWrapper<ExamPaper> queryWrapper = new LambdaQueryWrapper<>();
        if (personnelType != null && personnelType != PersonnelTypeEnum.DEFAULT.getCode()) {
            queryWrapper.eq(ExamPaper::getPersonnelType, personnelType);
        }
        if(moduleType != null){
            queryWrapper.eq(ExamPaper::getModuleType, moduleType);
        }
        if(StringUtils.isNotBlank(paperName)){
            queryWrapper.likeRight(ExamPaper::getPaperName, paperName);
        }
        queryWrapper.eq(ExamPaper::getDeleteFlag, 0L);
        queryWrapper.orderByDesc(ExamPaper::getUpdateTime);
        return list(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(ExamPaperDto examPaperDto) {
        ExamPaper examPaper;
        if(examPaperDto.getPaperId() != null){
            QueryWrapper<ExamPaper> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("paper_id", examPaperDto.getPaperId());
            examPaper = examPaperMapper.selectOne(queryWrapper);
            if(examPaper == null){
                throw new MyRuntimeException("不存在的试卷");
            }
        }else{
            examPaper = new ExamPaper();
        }
        BeanUtils.copyProperties(examPaperDto, examPaper);
        examPaper.setSubjectCount(examPaperDto.getSubjects().size());
        if(examPaper.getPaperId() != null){
            examPaper.setUpdateTime(new Date());
            examPaperMapper.update(examPaper, new QueryWrapper<ExamPaper>().eq("paper_id", examPaper.getPaperId()));
            examPaperDetailMapper.deleteByPaperId(examPaper.getPaperId());
        }else{
            examPaper.setCreateTime(new Date());
            examPaperMapper.insert(examPaper);
        }
        List<ExamPaperDetail> details = new ArrayList<>();
        examPaperDto.getSubjects().forEach(subject -> {
            ExamPaperDetail detail = new ExamPaperDetail();
            detail.setPaperId(examPaper.getPaperId());
            detail.setSubjectId(subject.getSubjectId());
            SubjectFrontVo subjectFrontVo = subjectService.findFrontBySubjectId(detail.getSubjectId());
            detail.setSubjectContent(JSONUtil.toJsonStr(subjectFrontVo));
            detail.setCreateTime(new Date());
            details.add(detail);
        });
        detailService.saveBatch(details);
    }

    @Override
    public void deleteExamPaper(Long paperId) {
        ExamPaper exist = examPaperMapper.selectByPaperId(paperId);
        if(exist != null){
            examPaperDetailMapper.deleteByPaperId(paperId);
            examPaperMapper.deleteById(paperId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void refreshExamPaper(Long paperId) {
        QueryWrapper<ExamPaper> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("paper_id", paperId);
        ExamPaper examPaper = examPaperMapper.selectOne(queryWrapper);
        if(examPaper != null){
            QueryWrapper<ExamPaperDetail> detailQueryWrapper = new QueryWrapper<>();
            detailQueryWrapper.eq("paper_id", examPaper.getPaperId());
            List<ExamPaperDetail> details = examPaperDetailMapper.selectList(detailQueryWrapper);
            details.forEach(detail -> {
                SubjectFrontVo subjectFrontVo = subjectService.findFrontBySubjectId(detail.getSubjectId());
                detail.setSubjectContent(JSONUtil.toJsonStr(subjectFrontVo));
            });
            examPaperDetailMapper.deleteByPaperId(paperId);
            detailService.saveBatch(details);
        }
    }

    @Override
    public ExamPaper findById(Long paperId) {
        QueryWrapper<ExamPaper> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("paper_id", paperId);
        return examPaperMapper.selectOne(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void publish(Long paperId) {
        ExamPaper examPaper = findById(paperId);
        if(examPaper != null){
            int personnelType = examPaper.getPersonnelType();
            examPaperMapper.resetPublish(personnelType);
            examPaper.setPublished(true);
            examPaperMapper.update(examPaper, new QueryWrapper<ExamPaper>().eq("paper_id", examPaper.getPaperId()));
        }
    }

    @Override
    public ExamPaper findPublishedPaper(Integer personnelType, Integer moduleType) {
        QueryWrapper<ExamPaper> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("personnel_type", personnelType);
        queryWrapper.eq("module_type", moduleType);
        queryWrapper.eq("published", true);
        return examPaperMapper.selectOne(queryWrapper);
    }

    @Override
    public void logicDelete(Long paperId) {
        ExamPaper examPaper = examPaperMapper.selectByPaperId(paperId);
        if(examPaper == null){
            throw  new MyRuntimeException("不存在的试卷");
        }

        long exist = examService.existExam(paperId);
        if(exist > 0){
            throw new MyRuntimeException("试卷已被发布且存在考试记录，不能删除");
        }

        examPaper.setDeleteFlag(System.currentTimeMillis());
        examPaper.setUpdateTime(new Date());
        examPaperMapper.update(examPaper, new QueryWrapper<ExamPaper>().eq("paper_id", paperId));
    }
}
